<?php

namespace App\Http\Controllers\Wechat;

use App\Http\Controllers\RedisServiceController;
use App\Jobs\AnswerActivityDrawJob;
use App\Models\AnswerActivity;
use App\Models\AnswerActivityUserGift;
use App\Models\AnswerActivityUserPrize;
use App\Models\AnswerActivityUserUsePrizeRecord;
use App\Validate\AnswerActivityDrawValidate;
use Exception;
use Illuminate\Support\Facades\DB;

/**
 * 答题活动抽奖管理
 */
class AnswerActivityDrawController extends CommonController
{

    public $not_winning_msg = '很遗憾，未中奖'; //未中奖文案
    public $answer_activity_draw_key = 're_answer_activity_draw';
    public $model = null;
    public $activityModel = null;
    public $validate = null;

    public function __construct()
    {
        parent::__construct();

        $this->model = new AnswerActivityUserPrize();
        $this->activityModel = new AnswerActivity();
        $this->validate = new AnswerActivityDrawValidate();
    }

    /**
     * 开始抽奖
     * @param timestamp  时间戳  13位
     * @param sign  签名  token 拼接 sign_key 拼接 时间戳  然后  md5后值 在全部转大写的值
     * @param token  用户guid
     * @param act_id int 活动id
     */
    public function draw()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('draw')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        //验证签名是否正确
        if (!$this->verifySignature($this->request->timestamp, $this->request->token, $this->request->sign)) {
            return $this->returnApi(201, '签名错误');
        }

        $act_info = $this->activityModel->detail($this->request->act_id);

        if (empty($act_info)) {
            return $this->returnApi(201, '参数错误');
        }
        if ($act_info['prize_form'] != 2) {
            return $this->returnApi(201, '此活动不是抽奖类活动，不允许抽奖');
        }

        // if ($act_info['lottery_start_time'] > date('Y-m-d H:i:s') || $act_info['lottery_end_time'] < date('Y-m-d H:i:s')) {
        //     return $this->returnApi(201, '不在抽奖时间段内');
        // }

        //抽奖状态 判断
        $status = $this->activityModel->isCanDraw($act_info, $this->request->token);
        if ($status !== true) {
            return $this->returnApi(201,  $status);
        }

        //查看当前用户是否有正在抽奖的任务，有禁止继续抽奖
        $redisObj = RedisServiceController::getInstance();
        //判断订单号是否存在
        $is_exists = $redisObj->valueExists($this->answer_activity_draw_key . $this->request->token);
        if ($is_exists) {
            return $this->returnApi(201, '正在抽奖中，请勿重复操作');
        }


        $isHavePrizeNumber = $this->model->isHavePrizeNumber($this->request->act_id, $this->request->token);
        if (!$isHavePrizeNumber) {
            return $this->returnApi(201, '无抽奖次数');
        }

        //获取订单号
        $answerActivityUserUsePrizeRecordModel = new AnswerActivityUserUsePrizeRecord();
        $order_id = $answerActivityUserUsePrizeRecordModel->getDrawOrderId(10, $this->answer_activity_draw_key);
        if (empty($order_id)) {
            return $this->returnApi(201, '当前抽奖人数过多，请稍后重试');
        }
        //写入队列
        $data = [
            'act_id' => $this->request->act_id,
            'user_guid' => $this->request->token,
            'order_key' => $this->answer_activity_draw_key,
            'order_id' => $order_id,
            'create_time' => date("Y-m-d H:i:s"),
            'date' => date("Y-m-d"),
            'hour' => date("H")
        ];

        //数据写入 队列，然后再监听程序（php artisan queue:listen），
        //会自动找到 对应控制器进行处理，这里的参数与 控制器 构造方法参数对应，即使同时有多个队列，也会找到对应控制器去处理，不用我们代码处理，都为这个为主（new AnswerActivityDrawJob）
        //在监听后，程序会自动把参数放到对应位置
        $queue_id = dispatch(new AnswerActivityDrawJob($this->answer_activity_draw_key, $data))->onQueue($this->answer_activity_draw_key); //执行完后就不用管了，也不用管另外一个控制器怎么拿的到这些参数，各写各的逻辑即可

        if (!$queue_id) {
            return $this->returnApi(202, '网络错误,请稍后重试');
        }

        //用户正在抽奖中
        $redisObj->setRedisValue($this->answer_activity_draw_key . $this->request->token, $order_id, 3600 * 2);
        $redisObj->setRedisValue($this->answer_activity_draw_key . $order_id, $order_id, 3600 * 2);

        sleep(1); //等1秒

        return $this->returnApi(200, '操作成功', true, ['order_id' => $order_id]);
    }

    /**
     * 获取抽奖结果
     * @param timestamp  时间戳  13位
     * @param sign  签名  token 拼接 sign_key 拼接 时间戳  然后  md5后值 在全部转大写的值
     * @param order_id 订单号
     * @param token 用户guid
     */
    public function getDrawResult()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('get_draw_result')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        //验证签名是否正确
        if (!$this->verifySignature($this->request->timestamp, $this->request->token, $this->request->sign)) {
            return $this->returnApi(202, '签名错误');
        }

        $order_id = $this->request->order_id;
        $token = $this->request->token;
        $redisObj = RedisServiceController::getInstance();

        //判断订单号是否存在,不存在，直接未中奖
        $is_exists = $redisObj->valueExists($this->answer_activity_draw_key . $order_id);
        if (!$is_exists) {
            return $this->returnApi(209, $this->not_winning_msg);
        }

        $answerActivityUserGiftModel = new AnswerActivityUserGift();
        $answerActivityUserUsePrizeRecordModel = new AnswerActivityUserUsePrizeRecord();
        $userPrizeRecord = $answerActivityUserUsePrizeRecordModel->where('order_id', $order_id)->first();
        if (empty($userPrizeRecord)) {
            sleep(1); //未获取到结果，先等一段时间在获取第二次 ,前端已经等待 500毫秒了
            return $this->returnApi(208, '正在获取抽奖结果，请稍等...');
        }

        $redisObj->delRedisValue($this->answer_activity_draw_key . $order_id); //删除redis



        if ($userPrizeRecord['user_guid'] != $token) {
            return $this->returnApi(202, '网络错误');
        }
        if ($userPrizeRecord['status'] == 2) {
            return $this->returnApi(209, $this->not_winning_msg);
        }
        //获取奖品
        $userGift = $answerActivityUserGiftModel->getUserGiftInfo($order_id);
        if (empty($userGift)) {
            return $this->returnApi(209, $this->not_winning_msg);
        }

        // $redisObj->delRedisValue($order_id);//删除订单号,抽奖结束后已删除，无需再次删除

        return $this->returnApi(200, '已中奖', true, [
            'name' => $userGift['name'], //礼物名称
            'img' => $userGift['img'], //礼物图片
            'intro' => $userGift['intro'], //礼物简介
            'price' => $userGift['price'], //金额
            'type' => $userGift['type'], //类型 1文化红包 2精美礼品
            'create_time' => $userGift['create_time'], //中奖时间
        ]);
    }
}
